package com.cnebula.openapi.auth.authtoken.impl;

import com.cnebula.openapi.auth.authtoken.AccessTokenService;
import com.cnebula.openapi.auth.authtoken.MainOptions;
import com.cnebula.openapi.auth.authtoken.TokenCreator;
import com.cnebula.openapi.auth.authtoken.exception.AccessTokenExpireException;
import com.cnebula.openapi.auth.authtoken.exception.AccessTokenIllegalException;
import com.cnebula.openapi.auth.authtoken.exception.RedisClientException;

import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.redis.RedisClient;
import io.vertx.redis.RedisOptions;

public class AccessTokenServiceImpl implements AccessTokenService {

	RedisClient redis;
	Vertx vertx;

	public AccessTokenServiceImpl(Vertx vertx, MainOptions options) {

		this.vertx = vertx;
		RedisOptions redisOptions = new RedisOptions();
		redisOptions.setHost(options.getRedisHost());
		redisOptions.setPort(options.getRedisPort());
		
		redis = RedisClient.create(vertx, redisOptions);
	}

	public Future<Void> checkToken(String token, TokenCreator tokenCreator) {

		Future<Void> future = Future.future();
		try {
			tokenCreator.checkToken(token);
			future.complete();
			return future;
		} catch (MalformedJwtException | UnsupportedJwtException e) {
			future.fail(new AccessTokenIllegalException());
		} catch (Exception e) {
			redis.get(token, h -> {
				if (h.succeeded()) {
					if (h.result() == null || h.result().equals("")) {
						future.fail(new AccessTokenExpireException());
					} else {
						future.complete();
					}

				} else {
					future.fail(new RedisClientException(h.cause()));
				}
			});
		}

		return future;

	}
}
